New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support CPU profiling sections of code #3971
Conversation
Signed-off-by: Breezewish <breezewish@pingcap.com>
Do we need to install gperftools at first? |
28285d6
to
5d8d429
Compare
Signed-off-by: Breezewish <breezewish@pingcap.com>
5d8d429
to
9ddf5e9
Compare
@siddontang Yes. I copied the manual from code to the PR description now. I also updated the code to support Callgrind (so that we can profile cache hit etc). |
Signed-off-by: Breezewish <breezewish@pingcap.com>
Signed-off-by: Breezewish <breezewish@pingcap.com>
This comment has been minimized.
This comment has been minimized.
So if the user doesn't install perftools, can it build TiKV now? I suggest you introduce valgrind in another PR. |
@siddontang Yes. Only when profiling feature is enabled, gperftools is required. As you can see, it builds normally on Circle CI and our own Jenkins CI. The support of Valgrind is only 4 lines of code. It should not be a big problem. |
do we need to install vagrind manally too? |
IMO, if we build with this feature, we don't need using environment forcibly to control it. Only calling start and stop is enough. |
@siddontang Don't need to install valgrind to build it. Ok |
Updated. No need to set "TIKV_PROFILE=1" now. |
Signed-off-by: Breezewish <breezewish@pingcap.com>
Signed-off-by: Breezewish <breezewish@pingcap.com>
@brson PTAL for this~ Thanks a lot! |
Signed-off-by: Breezewish <breezewish@pingcap.com>
This is very cool @breeswish. I guess that the idea is to insert start and stop temporarily and then remove them when done? Otherwise there's a lot of deadlock potential. One nice change would be to change the profiler manifest to make all the dependencies optional (particularly the profiling deps), and have the Is there anything holding up landing this? Maybe docs - like the allocator configuration this seems like something that should be surfaced in a developer's guide. Not necessary for this PR though. |
Signed-off-by: Breezewish <breezewish@pingcap.com>
@brson @kennytm Thanks a lot for reviewing! I have updated my
Yes. A better way maybe, provide interfaces to trigger a start and stop it moment later so that a profile can be generated. This does not introduce runtime costs when profiling is not started. The interface can be our status server like #4444
Nop, it's just lack of reviewers previously :) |
I think we can advance this PR now. |
@siddontang We can have another PR that utilize the interface via HTTP API. |
PTAL @brson |
@siddontang acknowledged that we want an HTTP interface, and that this is a good start. |
lgtm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can gperftools be installed automatically?
publish = false | ||
|
||
[features] | ||
profiling = ["lazy_static", "cpuprofiler", "callgrind", "valgrind_request"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it compile on Windows without the feature enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should work though I don't have a Windows machine. I changed it to [target.'cfg(linux)'.dependencies]
and it can compile on my MacOS.
//! Also see `examples/prime.rs`. | ||
|
||
#[allow(unused_extern_crates)] | ||
extern crate tikv_alloc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use tikv_alloc
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tikv_alloc generally needs to be linked into every crate that doesn't link to tikv, so that tests and benches of that crate use tikv's allocator. I don't think this extern crate statement is needed though as long as the dependency exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CI will fail if alloc is not linked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right. There are tests that all binaries contain jemalloc.
[target.'cfg(unix)'.dependencies] | ||
lazy_static = { version = "1.2.0", optional = true } | ||
cpuprofiler = { version = "0.0.3", optional = true } | ||
callgrind = { version = "1.1.0", optional = true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is valgrind a useful use case? I think most of the time only cpuprofiling is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
valgrind is very useful for micro benchmark, which can report precise amount of function calls, as well as precise (emulated) cache hit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm also hoping that this crate can be extended into a general purpose profiling module that can be published for the community, and ultimately fulfill the various requirements of the Go profiling tools. More profiler options in that case seems good.
Signed-off-by: Breezewish <breezewish@pingcap.com>
Signed-off-by: Breezewish <breezewish@pingcap.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: Breezewish <breezewish@pingcap.com>
Signed-off-by: Breezewish <breezewish@pingcap.com>
Signed-off-by: Breezewish breezewish@pingcap.com
What have you changed? (mandatory)
We usually need to find out why specific sections of code are slow. However, sometimes it cannot be done via simple perf, i.e. when there is a bootstrap. This PR provides facility to programmatically start or stop CPU profiling. In this way, we can start profiling before our interested code begins and stop profiling after it ends.
We can explore more interesting usages in the future, i.e. toggle profiling dynamically via signals, or environment variables. Future PRs are welcome!
The manual is in the code. I paste it here for easy reading:
Profile a part of the code using CPU Profiler from gperftools or Callgrind.
Requirements
Linux
Other OS may also work however, not tested.
gperftools
You can follow its INSTALL manual.
Roughly the instructions are the following:
./configure
make install
Usage
Then, compile the code with
profiling
feature enabled and run the code with environmentvariable
TIKV_PROFILE=1
.By default, a profile called
app.profile
will be generated by CPU Profiler.You can then analyze the profile using pprof.
If the application is running in Callgrind, a Callgrind profile dump will be generated instead.
Notice that you should run Callgrind with command line option
--instr-atstart=no
, e.g.:Also see
examples/prime.rs
.